-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Locking channel accounts to transactions #116
Conversation
Instead of locking channel accounts for an arbitrary amount of time, lock them for the same amount of time as the transaction time bounds and also explicitly lock them to transactions, unlocking them in the webhook channel
internal/db/migrations/2025-01-22.0-add_locked_tx_hash_to_channel_accounts.sql
Outdated
Show resolved
Hide resolved
func (sc *channelAccountDBSignatureClient) GetAccountPublicKey(ctx context.Context, opts ...int) (string, error) { | ||
var lockedUntil time.Duration | ||
if len(opts) > 0 { | ||
lockedUntil = time.Duration(opts[0]) * time.Second | ||
} else { | ||
lockedUntil = time.Minute | ||
} | ||
for range store.ChannelAccountWaitTime { | ||
channelAccount, err := sc.channelAccountStore.GetIdleChannelAccount(ctx, time.Minute) | ||
// check to see if the variadic parameter for time exists and if so, use it here | ||
channelAccount, err := sc.channelAccountStore.GetIdleChannelAccount(ctx, lockedUntil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this function accept multiple integers? I only see the first one used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to pass in the time for which to lock a channel account as an optional argument, so that not every signature client has to pass it in, which is why I made it a variadic function
@@ -29,20 +29,20 @@ func (ca *ChannelAccountModel) GetIdleChannelAccount(ctx context.Context, locked | |||
query := fmt.Sprintf(` | |||
UPDATE channel_accounts | |||
SET | |||
locked_tx_hash = NULL, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is unnecessary since UnlockChannelAccountFromTx()
sets this to null
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is true in theory, but in case the channel accounts do not get unlocked (they fail to reach the webhook for example), this will act as a fail safe, which is why I added it in there
resolves #102 |
What
Instead of locking channel accounts for an arbitrary amount of time like we are currently doing, lock them for the same amount of time as the transaction time bounds and also explicitly lock them to transactions (when the transaction is being built), opportunistically unlocking them from their transactions in the webhook channel
Why
If the channel account is specified as the source of a transaction that hasn't been accepted by the network yet, and the same channel account is "unlocked" and then used as the source for a different transaction that gets accepted by the network prior to the original, the original transaction is invalidated. We want to avoid this behavior
Known limitations
N/A
Issue that this PR addresses
https://github.com/orgs/stellar/projects/58/views/2?pane=issue&itemId=92871835&issue=stellar%7Cwallet-backend%7C102
Checklist
PR Structure
all
if the changes are broad or impact many packages.Thoroughness
Release